----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    10:40:56 12/02/2008 
-- Design Name: 
-- Module Name:    full_fft - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 1.00a - forward & reverse fft working correctly
--			1.01a - changed mode to unscaled
-- Additional Comments: 
------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity full_fft is
    Port (	clk_100M : in  STD_LOGIC;
				clk_48k : in std_logic;
				reset : in  STD_LOGIC;
				
				fwd_inv : in std_logic;
				enable : in std_logic;
			  
				x0_re : in  STD_LOGIC_VECTOR (23 downto 0);
				x0_im : in  STD_LOGIC_VECTOR (23 downto 0);
				y0_re : out  STD_LOGIC_VECTOR (23 downto 0);
				y0_im : out  STD_LOGIC_VECTOR (23 downto 0);
		   
				done : out std_logic;
		   
				sample_number : out std_logic_vector(7 downto 0);
			
				debug : out std_logic_vector(3 downto 0));
end full_fft;

architecture Behavioral of full_fft is
	COMPONENT dcm_200
	PORT(
		CLKIN_IN : IN std_logic;
		RST_IN : IN std_logic;          
		CLKFX_OUT : OUT std_logic;
		CLK0_OUT : OUT std_logic
		);
	END COMPONENT;
	
	component butterfly is
		Port ( clk : in  STD_LOGIC;
				 reset : in  STD_LOGIC;
				 start : in std_logic;
				 fwd_inv : in std_logic;
				 x0_re : in  STD_LOGIC_vector(23 downto 0);
				 x0_im : in  STD_LOGIC_vector(23 downto 0);
				 x1_re : in  STD_LOGIC_vector(23 downto 0);
				 x1_im : in  STD_LOGIC_vector(23 downto 0);
				 twiddle_re: in std_logic_vector(15 downto 0);
				 twiddle_im: in std_logic_vector(15 downto 0);
				 y0_re : out  STD_LOGIC_vector(23 downto 0);
				 y0_im : out  STD_LOGIC_vector(23 downto 0);
				 y1_re : out  STD_LOGIC_vector(23 downto 0);
				 y1_im : out  STD_LOGIC_vector(23 downto 0);
				 data_valid: out std_logic
				 );
	end component;
	
	--twiddle factor calculation with MATLAB:
	--
	--W = zeros(1,N/2);
	--for loop = 1:N/2
   --		W(loop) = exp(-(fwd_inv*2*pi*(loop-1)*i)/N);
	--end
	--X = floor(W * 16384)	%X <= 16 bit fixed point
	--twiddle_re = dec2bin(real(X), 16);
	--twiddle_re = dec2bin(imag(X), 16);
	component bram_16x64re IS
	port (
		addr: IN std_logic_VECTOR(5 downto 0);
		clk: IN std_logic;
		dout: OUT std_logic_VECTOR(15 downto 0));
	END component bram_16x64re;
	
	component bram_16x64im IS
	port (
		addr: IN std_logic_VECTOR(5 downto 0);
		clk: IN std_logic;
		dout: OUT std_logic_VECTOR(15 downto 0));
	END component bram_16x64im;
	
	component bram_24x128 IS
	port (
		addra: IN std_logic_VECTOR(6 downto 0);
		addrb: IN std_logic_VECTOR(6 downto 0);
		clka: IN std_logic;
		clkb: IN std_logic;
		dina: IN std_logic_VECTOR(23 downto 0);
		dinb: IN std_logic_VECTOR(23 downto 0);
		douta: OUT std_logic_VECTOR(23 downto 0);
		doutb: OUT std_logic_VECTOR(23 downto 0);
		wea: IN std_logic;
		web: IN std_logic);
	END component bram_24x128;
	
	--BRAM signals
	signal memory_in_re_addra	: std_logic_vector(6 downto 0)	:= (others => '0');
	signal memory_in_re_dina 	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_in_re_douta	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_in_re_wea 	: std_logic								:= '0';
	signal memory_in_im_addra	: std_logic_vector(6 downto 0)	:= (others => '0');
	signal memory_in_im_dina 	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_in_im_douta	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_in_im_wea 	: std_logic								:= '0';
	signal memory_in_re_addrb	: std_logic_vector(6 downto 0)	:= (others => '0');
	signal memory_in_re_dinb 	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_in_re_doutb	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_in_re_web		: std_logic								:= '0';
	signal memory_in_im_addrb	: std_logic_vector(6 downto 0)	:= (others => '0');
	signal memory_in_im_dinb 	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_in_im_doutb	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_in_im_web		: std_logic								:= '0';
	
	signal memory_out_re_addra	: std_logic_vector(6 downto 0)	:= (others => '0');
	signal memory_out_re_dina 	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_out_re_douta	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_out_re_wea	: std_logic								:= '0';
	signal memory_out_im_addra	: std_logic_vector(6 downto 0)	:= (others => '0');
	signal memory_out_im_dina 	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_out_im_douta	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_out_im_wea	: std_logic								:= '0';
	signal memory_out_re_addrb	: std_logic_vector(7 downto 0)	:= (others => '0');
	signal memory_out_re_dinb 	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_out_re_doutb	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_out_re_web	: std_logic								:= '0';
	signal memory_out_im_addrb	: std_logic_vector(7 downto 0)	:= (others => '0');
	signal memory_out_im_dinb 	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_out_im_doutb	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_out_im_web	: std_logic								:= '0';
	
	--multi-source handling signals
	--signals with _d1 have an added delay, and will change on the next positive flank of
	--the clk_100M, to ensure correct memory functionality
	signal memory_in_re_write_addra		: std_logic_vector(6 downto 0)	:= (others => '0');
	signal memory_in_re_write_addra_d1	: std_logic_vector(6 downto 0)	:= (others => '0');
	signal memory_in_re_fft_addra			: std_logic_vector(7 downto 0)	:= (others => '0');
	signal memory_in_im_write_addra		: std_logic_vector(6 downto 0)	:= (others => '0');
	signal memory_in_im_write_addra_d1	: std_logic_vector(6 downto 0)	:= (others => '0');
	signal memory_in_im_fft_addra			: std_logic_vector(7 downto 0)	:= (others => '0');
	signal memory_in_re_fft_addrb			: std_logic_vector(7 downto 0)	:= (others => '0');
	signal memory_in_im_fft_addrb			: std_logic_vector(7 downto 0)	:= (others => '0');
	signal memory_in_re_write_wea			: std_logic								:= '0';
	signal memory_in_re_write_wea_d1		: std_logic								:= '0';
	signal memory_in_im_write_wea			: std_logic								:= '0';
	signal memory_in_im_write_wea_d1		: std_logic								:= '0';
	signal memory_in_re_write_dina		: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_in_re_write_dina_d1	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_in_im_write_dina		: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_in_im_write_dina_d1	: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_in_re_fft_wea			: std_logic								:= '0';
	signal memory_in_im_fft_wea			: std_logic								:= '0';
	signal memory_in_re_fft_dina			: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_in_im_fft_dina			: std_logic_vector(23 downto 0)	:= (others => '0');
	signal memory_out_re_read_addra		: std_logic_vector(6 downto 0)	:= (others => '0');
	signal memory_out_im_read_addra		: std_logic_vector(6 downto 0)	:= (others => '0');
	signal memory_out_re_fft_addra		: std_logic_vector(7 downto 0)	:= (others => '0');
	signal memory_out_im_fft_addra		: std_logic_vector(7 downto 0)	:= (others => '0');
	
	signal start			: std_logic								:= '0';
	signal data_valid 	: std_logic								:= '0';
	signal state			: integer range 0 to 3				:= 0;
	signal j					: std_logic_vector(7 downto 0)	:= (others => '0');
	signal k					: std_logic_vector(7 downto 0)	:= (others => '0');
	signal l					: std_logic_vector(7 downto 0)	:= (others => '0');
	signal index			: std_logic_vector(7 downto 0)	:= (others => '0');
	signal step				: std_logic_vector(7 downto 0)	:= (others => '0');
	signal twiddle_addr	: std_logic_vector(5 downto 0)	:= (others => '0');
	signal memory_delay	: std_logic_vector(1 downto 0)	:= "00";
	signal last_value		: std_logic	:= '0';
	
	signal input_data_ready : std_logic 							:= '0';
	signal output_data_ready: std_logic								:= '0';
	signal counter_in			: std_logic_vector(7 downto 0)	:= (others => '0');
	signal counter_in_bitrev: std_logic_vector(7 downto 0)	:= (others => '0');
	signal counter_out		: std_logic_vector(7 downto 0)	:= (others => '0');
	
	signal x0_re_i				: std_logic_vector(23 downto 0)	:= (others => '0');
	signal x0_im_i				: std_logic_vector(23 downto 0)	:= (others => '0');
	signal x1_re_i				: std_logic_vector(23 downto 0)	:= (others => '0');
	signal x1_im_i				: std_logic_vector(23 downto 0)	:= (others => '0');
	signal twiddle_re_i		: std_logic_vector(15 downto 0)		:= (others => '0');
	signal twiddle_im_i		: std_logic_vector(15 downto 0)		:= (others => '0');
	signal y0_re_i				: std_logic_vector(23 downto 0)	:= (others => '0');
	signal y0_im_i				: std_logic_vector(23 downto 0)	:= (others => '0');
	signal y1_re_i				: std_logic_vector(23 downto 0)	:= (others => '0');
	signal y1_im_i				: std_logic_vector(23 downto 0)	:= (others => '0');
begin
	
	--handle multi-source signals
	memory_in_re_addra	<= memory_in_re_write_addra_d1 	when not(state = 1) else memory_in_re_fft_addra(6 downto 0);
	memory_in_im_addra	<= memory_in_im_write_addra_d1 	when not(state = 1) else memory_in_im_fft_addra(6 downto 0);
	memory_in_re_addrb	<= memory_in_re_fft_addrb(6 downto 0);
	memory_in_im_addrb	<= memory_in_im_fft_addrb(6 downto 0);
	memory_in_re_wea		<= memory_in_re_write_wea_d1		when not(state = 1) else memory_in_re_fft_wea;
	memory_in_im_wea		<= memory_in_im_write_wea_d1		when not(state = 1) else memory_in_im_fft_wea;
	memory_in_re_dina		<= memory_in_re_write_dina_d1		when not(state = 1) else memory_in_re_fft_dina;
	memory_in_im_dina		<= memory_in_im_write_dina_d1		when not(state = 1) else memory_in_im_fft_dina;
	
	memory_out_re_addra	<= memory_out_re_read_addra	when memory_out_re_wea = '0' else memory_out_re_fft_addra(6 downto 0);
	memory_out_im_addra	<= memory_out_im_read_addra	when memory_out_im_wea = '0' else memory_out_im_fft_addra(6 downto 0);
	
	--for no particular reason at this point
	debug <= input_data_ready & output_data_ready & memory_delay;
	
	input_p: process (clk_48k, reset)
	begin
		if reset = '0' then
			counter_in 			<= (others => '0');
			counter_in_bitrev <= (others => '0');
			input_data_ready 	<= '0';
			memory_in_re_write_addra <= (others => '0');
			memory_in_im_write_addra <= (others => '0');
			memory_in_re_write_dina	 <= (others => '0');
			memory_in_im_write_dina	 <= (others => '0');
			memory_in_re_write_wea	 <= '0';
			memory_in_im_write_wea	 <= '0';
			last_value <= '0';
		elsif clk_48k'event and clk_48k = '1' then
			if counter_in = "10000000" then						--counter = -128, actual overflow, but it doesnt matter, since we only use it to reset the counters
				input_data_ready <= '1';
				counter_in_bitrev <= (others => '0');
				counter_in <= (others => '0');
				--write last value to memory (127)
				last_value <= '1';
			elsif enable = '1' then
				last_value <= '0';
				counter_in <= counter_in + 1;
				--reverse bit order
				counter_in_bitrev(7) <= '0';						--make sure that index remains positive
				for i in 0 to 6 loop
					counter_in_bitrev(i) <= counter_in(6-i);
				end loop;
				
				input_data_ready <= '0';
			else
				last_value <= '0';
			end if;
		end if;
	end process;
	
	delay_p: process(clk_100M, reset)
	begin
		if reset = '0' then
			memory_in_re_write_addra_d1 <= (others => '0');
			memory_in_im_write_addra_d1 <= (others => '0');
			memory_in_re_write_dina_d1	 <= (others => '0');
			memory_in_im_write_dina_d1	 <= (others => '0');
			memory_in_re_write_wea_d1	 <= '0';
			memory_in_im_write_wea_d1	 <= '0';
		elsif clk_100M'event and clk_100M = '1' then
			if last_value = '1' then
				memory_in_re_write_addra_d1 <= "1111111";
				memory_in_im_write_addra_d1 <= "1111111";
				memory_in_re_write_dina_d1	 <= x0_re;
				memory_in_im_write_dina_d1	 <= x0_im;
				memory_in_re_write_wea_d1	 <= '1';
				memory_in_im_write_wea_d1	 <= '1';
			else
				memory_in_re_write_addra_d1 <= counter_in_bitrev(6 downto 0);
				memory_in_im_write_addra_d1 <= counter_in_bitrev(6 downto 0);
				memory_in_re_write_dina_d1	 <= x0_re;
				memory_in_im_write_dina_d1	 <= x0_im;
				memory_in_re_write_wea_d1	 <= '1';
				memory_in_im_write_wea_d1	 <= '1';
			end if;
		end if;
	end process;
	
	--positive edge triggered
	--output changes in this process
	output_data_p: process (clk_48k, reset)
	begin
		if reset = '0' then
			y0_re <= (others => '0');
			y0_im <= (others => '0');
		elsif clk_48k'event and clk_48k = '1' then
			if output_data_ready = '1' then
				y0_re <= memory_out_re_douta;
				y0_im <= memory_out_im_douta;
			else
				y0_re <= (others => '0');
				y0_im <= (others => '0');
			end if;
		end if;
	end process;
	
	--negative edge triggered
	--output address changes in this process
	output_address_p: process (clk_48k, reset)
	begin
		if reset = '0' then
			counter_out	<= "00000001";							--start at 1, as the first address will arrive as 0, since the positive clockflank will come first
			sample_number <= (others => '0');
			memory_out_re_read_addra <= (others => '0');
			memory_out_im_read_addra <= (others => '0');
		elsif clk_48k'event and clk_48k = '0' then
			if counter_out = "10000000" then
				counter_out <= "00000001";
				memory_out_re_read_addra <= (others => '0');
				memory_out_im_read_addra <= (others => '0');
				sample_number <= (others => '0');
			elsif output_data_ready = '1' then
				memory_out_re_read_addra 	<= counter_out(6 downto 0);
				memory_out_im_read_addra 	<= counter_out(6 downto 0);
				sample_number <= counter_out;
				counter_out <= counter_out + 1;
			end if;
		end if;
	end process;
	
	--body of the radix-2 DIT FFT
	--for full explanation, see documantation
	fft_body_p: process(clk_100M, reset)
	begin
		if reset = '0' then
			j <= (others => '0');
			k <= (others => '0');
			l <= (others => '0');
			start <= '0';
			state <= 0;
			output_data_ready <= '0';
			memory_delay <= "00";
			twiddle_addr <= "000000";
			done <= '0';
			step <= "01000000";					--start at 64
		elsif clk_100M'event and clk_100M = '1' then
			if state = 0 then 
				if input_data_ready = '1' then
					j <= (others => '0');
					k <= (others => '0');
					l <= (others => '0');
					index <= (others => '0');
					done <= '0';
					twiddle_addr <= "000000";			--start by fetching the first twiddle value
					step <= "01000000";					--start at 64
					state <= 1;
				end if;
			elsif state = 1 then
				if j < 6 then										--j < log(N)
					if k < 128 then								--k < N
						if l < shl("00000001", j) then		--l < 2^j
							if data_valid = '1' then
								memory_in_re_fft_addra	<= l+k;
								memory_in_im_fft_addra	<= l+k;
								memory_in_re_fft_addrb	<= l+k+shl("00000001", j);
								memory_in_im_fft_addrb	<= l+k+shl("00000001", j);
								memory_in_re_fft_wea		<= '1';
								memory_in_im_fft_wea		<= '1';
								memory_in_re_web			<= '1';
								memory_in_im_web			<= '1';
								memory_in_re_fft_dina	<= y0_re_i;			--in place
								memory_in_im_fft_dina	<= y0_im_i;			--in place
								memory_in_re_dinb			<= y1_re_i;			--in place
								memory_in_im_dinb			<= y1_im_i;			--in place
								start	<= '0';
								l <= l + 1;
							elsif start = '0' then
								if memory_delay = "00" then
									memory_in_re_fft_addra	<= l+k;
									memory_in_im_fft_addra	<= l+k;
									memory_in_re_fft_addrb	<= l+k+shl("00000001", j);
									memory_in_im_fft_addrb	<= l+k+shl("00000001", j);
									twiddle_addr <= index(5 downto 0);
									memory_in_re_fft_wea		<= '0';
									memory_in_im_fft_wea		<= '0';
									memory_in_re_web			<= '0';
									memory_in_im_web			<= '0';
									memory_delay <= "01";
								elsif memory_delay = "01" then
									memory_delay <= "10";
								else
									x0_re_i	<= memory_in_re_douta;		--in place
									x0_im_i	<= memory_in_im_douta;		--in place
									x1_re_i	<= memory_in_re_doutb;		--in place
									x1_im_i	<= memory_in_im_doutb;		--in place
									index <= index + step;
									start	<= '1';
									memory_delay <= "00";
								end if;
							end if;
						else
							l <= (others => '0');
							k <= k + shl("00000001", j+1);
							index <= (others => '0');
						end if;
					else
						k <= (others => '0');
						l <= (others => '0');
						j <= j + 1;
						step <= shr(step, "00000001");
					end if;
				elsif j = 6 then												--last stage, write to output memory
					output_data_ready <= '0';								--output data is no longer valid until finished writing
					if k < 128 then								--k < N
						if l < shl("00000001", j) then		--l < 2^j
							if data_valid = '1' then
								memory_out_re_fft_addra	<= l+k;
								memory_out_im_fft_addra	<= l+k;
								memory_out_re_addrb	<= l+k+shl("00000001", j);
								memory_out_im_addrb	<= l+k+shl("00000001", j);
								memory_out_re_wea	<= '1';
								memory_out_im_wea	<= '1';
								memory_out_re_web			<= '1';
								memory_out_im_web			<= '1';
								memory_out_re_dina	<= y0_re_i;			--to output memory
								memory_out_im_dina	<= y0_im_i;			--to output memory
								memory_out_re_dinb		<= y1_re_i;			--to output memory
								memory_out_im_dinb		<= y1_im_i;			--to output memory
								start	<= '0';
								l <= l + 1;
							elsif start = '0' then
								if memory_delay = "00" then
									memory_in_re_fft_addra	<= l+k;
									memory_in_im_fft_addra	<= l+k;
									memory_in_re_fft_addrb	<= l+k+shl("00000001", j);
									memory_in_im_fft_addrb	<= l+k+shl("00000001", j);
									twiddle_addr 			<= index(5 downto 0);
									memory_in_re_fft_wea		<= '0';
									memory_in_im_fft_wea		<= '0';
									memory_in_re_web			<= '0';
									memory_in_im_web			<= '0';
									memory_delay 				<= "01";
								elsif memory_delay = "01" then
									memory_delay <= "10";
								else
									x0_re_i			<= memory_in_re_douta;		--in place
									x0_im_i			<= memory_in_im_douta;		--in place
									x1_re_i			<= memory_in_re_doutb;		--in place
									x1_im_i			<= memory_in_im_doutb;		--in place
									index 			<= index + step;
									start				<= '1';
									memory_delay 	<= "00";
								end if;
							end if;
						else
							l <= (others => '0');
							k <= k + shl("00000001", j+1);
							index <= (others => '0');
						end if;
					else
						k <= (others => '0');
						l <= (others => '0');
						j <= j + 1;
						step <= shr(step, "00000001");
					end if;
				else
					j <= (others => '0');
					k <= (others => '0');
					l <= (others => '0');
					
					--prepare the first address for write
					memory_out_re_fft_addra	<= "00000000";
					memory_out_im_fft_addra	<= "00000000";
					--disable writing
					memory_out_re_wea		<= '0';
					memory_out_im_wea		<= '0';
					memory_out_re_web		<= '0';
					memory_out_im_web		<= '0';
				
					state <= 2;
				end if;
			elsif state = 2 then
				j <= (others => '0');
				k <= (others => '0');
				l <= (others => '0');
				index <= (others => '0');
				output_data_ready <= '1';
				done <= '1';
				
				if input_data_ready = '0' then		--wait for the input to become unready
					state <= 0;
				end if;
			end if;
		end if;
	end process;
	
	butter: butterfly port map(	clk 			=> clk_100M,
											reset			=> reset,
											start			=> start,
											fwd_inv		=> fwd_inv,
											x0_re			=>	x0_re_i,
											x0_im			=> x0_im_i,
											x1_re			=> x1_re_i,
											x1_im			=> x1_im_i,
											twiddle_re	=> twiddle_re_i,
											twiddle_im	=> twiddle_im_i,
											y0_re			=> y0_re_i,
											y0_im			=> y0_im_i,
											y1_re			=> y1_re_i,
											y1_im			=> y1_im_i,
											data_valid	=> data_valid
											);
											
	twiddle_re: bram_16x64re port map(
											addr			=> twiddle_addr,
											clk			=> clk_100M,
											dout			=> twiddle_re_i
											);
											
	twiddle_im: bram_16x64im port map(
											addr			=> twiddle_addr,
											clk			=> clk_100M,
											dout			=> twiddle_im_i
											);
	
	memory_in_re: bram_24x128 port map(
											addra		=> memory_in_re_addra,
											addrb		=> memory_in_re_addrb,
											clka		=> clk_100M,
											clkb		=> clk_100M,		
											dina		=> memory_in_re_dina,
											dinb		=> memory_in_re_dinb,
											douta		=> memory_in_re_douta,
											doutb		=> memory_in_re_doutb,
											wea		=> memory_in_re_wea,
											web		=> memory_in_re_web 
											);
	memory_in_im: bram_24x128 port map(
											addra		=> memory_in_im_addra,
											addrb		=> memory_in_im_addrb,
											clka		=> clk_100M,
											clkb		=> clk_100M,		
											dina		=> memory_in_im_dina,
											dinb		=> memory_in_im_dinb,
											douta		=> memory_in_im_douta,
											doutb		=> memory_in_im_doutb,
											wea		=> memory_in_im_wea,
											web		=> memory_in_im_web 
											);
	
	memory_out_re: bram_24x128 port map(
											addra		=> memory_out_re_addra,
											addrb		=> memory_out_re_addrb(6 downto 0),
											clka		=> clk_100M,
											clkb		=> clk_100M,		
											dina		=> memory_out_re_dina,
											dinb		=> memory_out_re_dinb,
											douta		=> memory_out_re_douta,
											doutb		=> memory_out_re_doutb,
											wea		=> memory_out_re_wea,
											web		=> memory_out_re_web 
											);
	memory_out_im: bram_24x128 port map(
											addra		=> memory_out_im_addra,
											addrb		=> memory_out_im_addrb(6 downto 0),
											clka		=> clk_100M,
											clkb		=> clk_100M,		
											dina		=> memory_out_im_dina,
											dinb		=> memory_out_im_dinb,
											douta		=> memory_out_im_douta,
											doutb		=> memory_out_im_doutb,
											wea		=> memory_out_im_wea,
											web		=> memory_out_im_web 
											);

end Behavioral;
